import type {
	UseStateToggleStatus,
	UseStateToggleBeforeChange,
	UseStateToggleParam,
} from './type';
import {MySet} from '../../util';

export default function<S>(
	{
		key,
		value,
		active,
		disabled,
		aloneActive,
		beforeChange,
		aloneValue,
		emit,
		rootRef,
	}:UseStateToggleParam<S>
){
	//region 值类型
	const modelType=():'set'|'array'|'custom'|false => {
		if(key()!==undefined){
			const val=value();
			if(Array.isArray(val)){
				return 'array';
			}else if(val instanceof MySet){
				return 'set';
			}else{
				return 'custom';
			}
		}
		return false;
	};
	//endregion
	//region 状态
	const activeStatus=():UseStateToggleStatus<S> => {
		const activeVal=active();
		if(activeVal==null){
			const val=value();
			const type=modelType();
			if(type==='array'){
				return val.indexOf(key())>-1;
			}else if(type==='set'){
				return val.value.has(key());
			}
			return aloneActive(val);
		}
		return activeVal;
	};
	//endregion
	//region 点击事件
	function _beforeChange(
		data:UseStateToggleBeforeChange<S>,
		callback:() => void,
	):void{
		Promise.resolve(beforeChange&&beforeChange(data)).then((success) => {
			if(success===false){
				throw 'beforeChange阻止';
			}
			callback();
		}).catch(function(){});
	}
	const clickFn=() => {
		if(disabled()) return;
		rootRef&&rootRef.value.blur();
		const type=modelType();
		const isActive=activeStatus();
		if(type){
			const keyVal=key();
			const val=value();
			_beforeChange({key:keyVal,active:isActive},() => {
				if(type==='array'){
					if(isActive){
						emit('update:modelValue',val.filter((e:any) => e!==keyVal));
					}else{
						emit('update:modelValue',val.concat([keyVal]));
					}
				}else if(type==='set'){
					if(isActive){
						val.delete(keyVal);
					}else{
						val.add(keyVal);
					}
				}
				if(isActive){
					emit('inactive',keyVal);
				}else{
					emit('active',keyVal);
				}
			});
		}else{
			_beforeChange(isActive,() => {
				emit('update:modelValue',aloneValue(isActive));
			});
		}
	};
	//endregion
	return {
		activeStatus,
		clickFn,
	};
}